;
; Boot.s -- Kernel start location. Also defines multiboot header.
;


MBOOT_PAGE_ALIGN    equ 1<<0    ; Load kernel and modules on a page boundary
MBOOT_MEM_INFO      equ 1<<1    ; Provide your kernel with memory info
MBOOT_HEADER_MAGIC  equ 0x1BADB002 ; Multiboot Magic value
; NOTE: We do not use MBOOT_AOUT_KLUDGE. It means that GRUB does not
; pass us a symbol table.
MBOOT_HEADER_FLAGS  equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO
MBOOT_CHECKSUM      equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)


[BITS 32]           ; Protected mode

[GLOBAL mboot]
[EXTERN code]
[EXTERN bss]
[EXTERN end]

mboot:
    dd 0                        ; See initialEsp below
    dd  MBOOT_HEADER_MAGIC  ; GRUB will search for this value on each
                                ; 4-byte boundary in your kernel file
    dd  MBOOT_HEADER_FLAGS  ; How GRUB should load your file / settings
    dd  MBOOT_CHECKSUM      ; To ensure that the above values are correct
    
    dd  mboot       ; Location of this descriptor
    dd  code        ; Start of kernel '.text' (code) section.
    dd  bss         ; End of kernel '.data' section.
    dd  end         ; End of kernel.
    dd  start       ; Kernel entry point (initial EIP).
        
[GLOBAL start]
[EXTERN _main]      ; This is the entry point of our C++ code
[EXTERN __main]
[GLOBAL initialEsp]

        ;; This is, unfortunately, a hack. We need to write to the variable
        ;; initialEsp, but if this is defined in a .cc file nasm doesn't pick it up.
        ;; so it has to be defined here. But, if it's in the .text segment nasm won't
        ;; assemble (intra-segment write), and the .data segment gets linked somewhere
        ;; random, so the only alternative is to reserve space at the start of the executable
        ;; (above: dd 0) then force initialEsp to appear at this location (below).
absolute 0x100000              
initialEsp resw 2

[SECTION .text]
start:
    ; Initial ESP
    mov [initialEsp], esp
        
    ; Load multiboot information:
    push    ebx

    ; Make the base pointer NULL here, so we know where to stop a backtrace.
    mov ebp, 0x0

    ; Execute the kernel:
    cli
    call    __main
    call    _main   ; Call 'int main(void)'
	jmp		$ 
